{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Leaflet cluster map of talk locations\n",
    "\n",
    "Assuming you are working in a Linux or Windows Subsystem for Linux environment, you may need to install some dependencies. Assuming a clean installation, the following will be needed:\n",
    "\n",
    "```bash\n",
    "sudo apt install jupyter\n",
    "sudo apt install python3-pip\n",
    "pip install python-frontmatter getorg --upgrade\n",
    "```\n",
    "\n",
    "After which you can run this from the `_talks/` directory, via:\n",
    "\n",
    "```bash\n",
    " jupyter nbconvert --to notebook --execute talkmap.ipynb --output talkmap_out.ipynb\n",
    "```\n",
    " \n",
    "The `_talks/` directory contains `.md` files of all your talks. This scrapes the location YAML field from each `.md` file, geolocates it with `geopy/Nominatim`, and uses the `getorg` library to output data, HTML, and Javascript for a standalone cluster map."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Start by installing the dependencies\n",
    "!pip install python-frontmatter getorg --upgrade\n",
    "import frontmatter\n",
    "import glob\n",
    "import getorg\n",
    "from geopy import Nominatim\n",
    "from geopy.exc import GeocoderTimedOut"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Collect the Markdown files\n",
    "g = glob.glob(\"_talks/*.md\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Set the default timeout, in seconds\n",
    "TIMEOUT = 5\n",
    "\n",
    "# Prepare to geolocate\n",
    "geocoder = Nominatim(user_agent=\"academicpages.github.io\")\n",
    "location_dict = {}\n",
    "location = \"\"\n",
    "permalink = \"\"\n",
    "title = \"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the event that this times out with an error, double check to make sure that the location is can be properly geolocated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Perform geolocation\n",
    "for file in g:\n",
    "    # Read the file\n",
    "    data = frontmatter.load(file)\n",
    "    data = data.to_dict()\n",
    "\n",
    "    # Press on if the location is not present\n",
    "    if 'location' not in data:\n",
    "        continue\n",
    "\n",
    "    # Prepare the description\n",
    "    title = data['title'].strip()\n",
    "    venue = data['venue'].strip()\n",
    "    location = data['location'].strip()\n",
    "    description = f\"{title}<br />{venue}; {location}\"\n",
    "\n",
    "    # Geocode the location and report the status\n",
    "    try:\n",
    "        location_dict[description] = geocoder.geocode(location, timeout=TIMEOUT)\n",
    "        print(description, location_dict[description])\n",
    "    except ValueError as ex:\n",
    "        print(f\"Error: geocode failed on input {location} with message {ex}\")\n",
    "    except GeocoderTimedOut as ex:\n",
    "        print(f\"Error: geocode timed out on input {location} with message {ex}\")\n",
    "    except Exception as ex:\n",
    "        print(f\"An unhandled exception occurred while processing input {location} with message {ex}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Save the map\n",
    "m = getorg.orgmap.create_map_obj()\n",
    "getorg.orgmap.output_html_cluster_map(location_dict, folder_name=\"talkmap\", hashed_usernames=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
